﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Data;

namespace EHR.Ctrls.QueryDesign
{
    public partial class GridDesign : UserControl
    {
        #region 字段
        private static readonly double _DefaultWidth = 80;
        private static readonly double _MinWidth = 20;

        private ViewDesignInfo _vi;
        private IList<ColInfo> _newColInfos;
        private bool _bEdgeDragging = false;
        private Point _mouseDownPosition;
        private double _moseDownColWidth;

        private bool _bColDragging = false;
        private double _mouseDownColX;
        private double _mouseDownAtColsPanelX;

        private GridDesignColumn _lendColumn;
        #endregion

        #region 构造方法
        public GridDesign()
        {
            InitializeComponent();
        }
        #endregion
        
        #region 辅助方法
        public void AddColumns(GridDesignColumn col)
        {
            col.MouseLeftButtonDown += new MouseButtonEventHandler(col_MouseLeftButtonDown);
            col.MouseLeftButtonUp += new MouseButtonEventHandler(col_MouseLeftButtonUp);
            col.MouseMove += new MouseEventHandler(col_MouseMove);
            col.LostMouseCapture += new MouseEventHandler(col_LostMouseCapture);
            panelColumns.Children.Add(col);
            //
            ColumnEdge edge = new ColumnEdge();
            edge.Column = col;
            edge.MouseLeftButtonDown += new MouseButtonEventHandler(edge_MouseLeftButtonDown);
            edge.MouseLeftButtonUp += new MouseButtonEventHandler(edge_MouseLeftButtonUp);
            edge.MouseMove += new MouseEventHandler(edge_MouseMove);
            edge.LostMouseCapture += new MouseEventHandler(edge_LostMouseCapture);
            Binding b = new Binding("Width");
            b.Source = col;
            edge.SetBinding(Control.WidthProperty, b);
            panelColEdges.Children.Add(edge);
        }

        void col_LostMouseCapture(object sender, MouseEventArgs e)
        {
            _bColDragging = false;
        }

        void col_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_bColDragging)
            {
                return;
            }
            GridDesignColumn col = sender as GridDesignColumn;
            Point pt = e.GetPosition(col);
            double atColsPanelX = e.GetPosition(panelColumns).X;
            Canvas.SetLeft(moveColHeader, _mouseDownColX + (atColsPanelX - _mouseDownAtColsPanelX));
            foreach (GridDesignColumn c in panelColumns.Children)
            {
                double x = e.GetPosition(c).X;

                if (c.MouseEnter(x))
                {
                    _lendColumn = c;
                }
            }
        }

        void col_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            GridDesignColumn col = sender as GridDesignColumn;
            col.ReleaseMouseCapture();
            _bColDragging = false;
            moveColHeader.Visibility = Visibility.Collapsed;
            if (_lendColumn == null)
            {
                return;
            }
            _lendColumn.MouseLeft();
            if (col != _lendColumn)
            {
                int colIndex = panelColumns.Children.IndexOf(col);
                panelColumns.Children.RemoveAt(colIndex);
                int lendIndex = panelColumns.Children.IndexOf(_lendColumn);
                panelColumns.Children.Insert(lendIndex + 1, col);

                ColumnEdge edge = panelColEdges.Children[colIndex] as ColumnEdge;
                panelColEdges.Children.Remove(edge);
                panelColEdges.Children.Insert(lendIndex + 1, edge);
            }
        }

        void col_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            GridDesignColumn col = sender as GridDesignColumn;
            _bColDragging = true;
            double atColX = e.GetPosition(col).X;
            _mouseDownAtColsPanelX = e.GetPosition(panelColumns).X;
            _mouseDownColX = _mouseDownAtColsPanelX - atColX;
            moveColHeader.Width = col.Width;
            Canvas.SetLeft(moveColHeader, _mouseDownColX);
            moveColTitle.Text = col.Title;
            moveColHeader.Visibility = Visibility.Visible;
            _lendColumn = null;
            col.CaptureMouse();
        }

        void edge_LostMouseCapture(object sender, MouseEventArgs e)
        {
            _bEdgeDragging = false;
        }

        void edge_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_bEdgeDragging)
            {
                return;
            }
            ColumnEdge edge = sender as ColumnEdge;

            Point ptMove = e.GetPosition(edge.Column);
            double w = ptMove.X - _mouseDownPosition.X;
            double nw = _moseDownColWidth + w;
            if (nw > _MinWidth)
            {
                edge.Column.Width = nw;
            }
        }

        void edge_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _bEdgeDragging = false;
            ColumnEdge edge = sender as ColumnEdge;
            edge.ReleaseMouseCapture();
        }

        void edge_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _bEdgeDragging = true;
            ColumnEdge edge = sender as ColumnEdge;
            edge.CaptureMouse();
            _mouseDownPosition = e.GetPosition(edge.Column);
            _moseDownColWidth = edge.Column.Width;
        }

        #endregion

        #region 公共方法
        public void SetViewInfo(ViewDesignInfo vi)
        {
            _vi = vi;
            txtViewName.Text = vi.ViewName;

            SetViewColumns(vi);
            SetViewFilter(vi);
            SetViewOrderBy(vi);
        }

        public ViewDesignInfo GetViewInfo()
        {
            ViewDesignInfo vi = _vi;
            vi.ViewName = txtViewName.Text.Trim();
            GetViewColumns();
            GetViewOrderBy(vi);
            GetViewFilter(vi);
            return vi;
        }

        public IList<ColInfo> GetNewColumns()
        {
            return _newColInfos;
        }

        public bool Validate()
        {
            if (string.IsNullOrWhiteSpace(txtViewName.Text))
            {
                txtViewName.Text = txtViewName.Text.Trim();
                MessageBox.Show("请输入视图名称！");
                txtViewName.Focus();
                return false;
            }

            bool bHaveColVisible = false;
            foreach (GridDesignColumn col in panelColumns.Children)
            {
                col.GetColInfo();
                if (col.IsVisible)
                {
                    bHaveColVisible = true;
                    break;
                }
            }

            if (!bHaveColVisible)
            {
                MessageBox.Show("至少显示一列！");
                return false;
            }

            if (!filterPanel.Validate())
            {
                return false;
            }

            return true;
        }
        #endregion

        #region 辅助方法
        private void SetViewColumns(ViewDesignInfo vi)
        {
            foreach (ColInfo col in vi.Columns)
            {
                AddColumns(new GridDesignColumn(col));
            }
        }

        private void SetViewFilter(ViewDesignInfo vi)
        {
            filterPanel.Columns = vi.Columns;
            foreach (FilterInfo fi in vi.Filters)
            {
                filterPanel.AddFilter(fi);
            }
        }

        private void SetViewOrderBy(ViewDesignInfo vi)
        {
            orderByPanel.SetColumns(vi.Columns);
            orderByPanel.SetOrderBys(vi.OrderBys);
        }

        private void GetViewColumns()
        {
            _newColInfos = new List<ColInfo>();
            foreach (GridDesignColumn col in panelColumns.Children)
            {
                _newColInfos.Add(col.GetColInfo());
            }
        }

        private void GetViewFilter(ViewDesignInfo vi)
        {
            vi.Filters = filterPanel.GetFilters();
        }

        private void GetViewOrderBy(ViewDesignInfo vi)
        {
            vi.OrderBys = orderByPanel.GetOrderBys();
        }
        #endregion

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            foreach (GridDesignColumn col in panelColumns.Children)
            {
                col.Visibility = col.IsVisible ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        private void chkHiddenCols_Unchecked(object sender, RoutedEventArgs e)
        {
            foreach (GridDesignColumn col in panelColumns.Children)
            {
                col.Visibility = Visibility.Visible;
            }
        }
    }
}
